/**
 * 
 */
package com.wgo.precise.client.ui.view.editor.usertypes;

import static com.wgo.precise.client.ui.controller.PrecisePluginImage.IMG_HORIZONTAL;
import static com.wgo.precise.client.ui.controller.PrecisePluginImage.IMG_VERTICAL;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.forms.DetailsPart;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.SectionPart;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;

import com.wgo.precise.client.ui.controller.listeners.IModelChangeListener;
import com.wgo.precise.client.ui.model.PropertyDefWrapper;
import com.wgo.precise.client.ui.model.PropertySetWrapper;
import com.wgo.precise.client.ui.model.facade.IModelPersistable;
import com.wgo.precise.client.ui.model.facade.INodeParent;
import com.wgo.precise.client.ui.view.editor.AbstractPartsFormPage;
import com.wgo.precise.client.ui.view.editor.IModelFormPart;
import com.wgo.precise.client.ui.view.util.ModelByteArrayTransfer;

/**
 * @author petterei
 *
 * @version $Id: UsertypesSectionPart.java,v 1.2 2006-01-30 21:52:32 petterei Exp $
 */
public class UsertypesSectionPart extends SectionPart implements IModelFormPart, IModelChangeListener {
	
	protected DetailsPart detailsPart;
	protected SashForm sashForm;

    private TableViewer viewer = null;
    private UserTypesTableContentProvider contentProvider = null;
    private CreateUserTypesTableRowAction createAction = null;
    private DeleteUserTypesTableRowAction deleteAction = null;
	private Action haction = null;
	private Action vaction = null;
	//    private ClientModelItem input = null;

    public UsertypesSectionPart(FormPage page, Composite parent) {
		super(page.getManagedForm().getToolkit().createSection(parent, Section.DESCRIPTION | ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED));
	}

	/**
	 * @see org.eclipse.ui.forms.AbstractFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
	 */
	@Override
	public void initialize(IManagedForm form) {
		super.initialize(form);
//		createContent(getManagedForm());
		createContent(getSection(), getManagedForm().getToolkit());
	}
	/**
	 * @see org.eclipse.ui.forms.AbstractFormPart#setFormInput(java.lang.Object)
	 */
	@Override
	public boolean setFormInput(Object input) {
		boolean inputOk = super.setFormInput(input);
		if (input instanceof PropertySetWrapper ) {
			viewer.setInput(input);
			inputOk = true;
		}
		return inputOk;
	}
	
	private void createContent(Section section, FormToolkit toolkit) {
		
		section.setText("UserDefined types");
		section.setDescription("Click on the cells to edit the values."); 
		section.setLayout(AbstractPartsFormPage.createLayout());
//		section.setLayout(AbstractFormPage.createLayout());  // is this necessary

		GridLayout layout = new GridLayout();
		layout.marginWidth = 0;
		layout.marginHeight = 0;

		Composite masterDetailsClient = toolkit.createComposite(section);											
//		FillLayout layout = (FillLayout)AbstractFormPage.createLayout();
//		layout.marginWidth = 1;
		masterDetailsClient.setLayout(layout);

		// add client to section?
	    section.setClient(masterDetailsClient);

//	    final ScrolledForm form = managedForm.getForm();

//		form.getBody().setLayout(layout);
//		sashForm = new SashForm(form.getBody(), SWT.NULL);
		sashForm = new SashForm(masterDetailsClient, SWT.NULL);
		toolkit.adapt(sashForm, false, false);
		
		sashForm.setMenu(getManagedForm().getForm().getBody().getMenu());
		
		sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));
//		createMasterPart(managedForm, sashForm);
		createMasterPart(sashForm, toolkit);
		createDetailsPart(getManagedForm(), sashForm);
//		createDetailsPart(managedForm, sashForm);
		
        createActions();
        contributeToActionBars();
        hookContextMenu();

//		form.updateToolBar();
	}

	private Table createMasterTable(FormToolkit toolkit, Composite parent) {
        int style = SWT.SINGLE | SWT.H_SCROLL | SWT.FULL_SELECTION  ;
//      int style = SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.HIDE_SELECTION;
		Table t = toolkit.createTable(parent, style);
//		Table t = toolkit.createTable(client, SWT.NULL);
		GridData gd = new GridData(GridData.FILL_BOTH);
		gd.heightHint = 20;
		gd.widthHint = 100;
		t.setLayoutData(gd);
	    toolkit.paintBordersFor(parent);
		return t;
    }

	private TableViewer createMasterTableViewer(FormToolkit toolkit, Table t) {
	    contentProvider = new UserTypesTableContentProvider();
	    TableViewer newViewer = new TableViewer(t);
        newViewer.setContentProvider(contentProvider);
        newViewer.setLabelProvider(new UserTypesTableLabelProvider());
        newViewer.setInput(getManagedForm().getInput());
        newViewer.setSorter(new UserTypesTableSorter());


        //drag
        int dragOperations = DND.DROP_MOVE;
        Transfer[] dragTransferTypes = new Transfer[] { ModelByteArrayTransfer.getInstance() };
        newViewer.addDragSupport(dragOperations, dragTransferTypes, new PropertySpecificationDragSourceListener(newViewer));
        //drop
        int dropOperations = DND.DROP_MOVE;
        Transfer[] dropTransferTypes = new Transfer[] { ModelByteArrayTransfer.getInstance() };
        newViewer.addDropSupport(dropOperations, dropTransferTypes, new UserDefinedTypesEditorPartDropAdapter(newViewer));
        
	    toolkit.adapt(newViewer.getControl(), true, true);
//	    ((Table)viewer.getControl()).setLinesVisible(true); 
	    return newViewer;
	}
	
	protected void createMasterPart(Composite parent, FormToolkit toolkit) {
		Section section = toolkit.createSection(parent, Section.DESCRIPTION | ExpandableComposite.TITLE_BAR);
		section.setText("Property Definitions");
		section.setDescription("The table contains property definitions from the template whose details are editable.");
		section.marginWidth = 10;
		section.marginHeight = 3;
		toolkit.createCompositeSeparator(section);
		Composite client = toolkit.createComposite(section, SWT.WRAP);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.marginWidth = 1;
		layout.marginHeight = 1;
		client.setLayout(layout);

		Table t = createMasterTable(toolkit, client);
		
		Button b = toolkit.createButton(client, "Add...", SWT.PUSH);
		GridData gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
		b.setLayoutData(gd);
		b.setToolTipText("Add property definition to template.");
		section.setClient(client);
		final SectionPart spart = new SectionPart(section);
		getManagedForm().addPart(spart);

		viewer = createMasterTableViewer(toolkit, t);

		// add the viewer..
		b.addSelectionListener(new CreateUserTypesTableRowAction(viewer));
		final IManagedForm managedFormFinal = getManagedForm();
		viewer.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				managedFormFinal.fireSelectionChanged(spart, event.getSelection());
			}
		});
	    refresh();
	}
	
	private void registerPages(DetailsPart newDetailsPart) {

//		detailsPart.registerPage(AbstractPropertySpesification.class, new PropertyDefinitionDetailsPage());
		newDetailsPart.registerPage(PropertyDefWrapper.class, new PropertyDefinitionDetailsPage());
//		detailsPart.registerPage(PropertySpecification.class, new CommonDetailsPage());
//		detailsPart.setPageProvider();
		// TODO Auto-generated method stub

	}


	private void createDetailsPart(final IManagedForm mform, Composite parent) {
		detailsPart = new DetailsPart(mform, parent, SWT.NULL);
		mform.addPart(detailsPart);
		registerPages(detailsPart);
	}
	
    private void createActions() {
        createAction = new CreateUserTypesTableRowAction(viewer);
        deleteAction = new DeleteUserTypesTableRowAction(viewer);

		final ScrolledForm form = getManagedForm().getForm();
		haction = new Action("hor", Action.AS_RADIO_BUTTON) {
			@Override
			public void run() {
				sashForm.setOrientation(SWT.HORIZONTAL);
				form.reflow(true);
			}
		};
		haction.setChecked(true);
		haction.setToolTipText("Horizontal orientation");
		haction.setImageDescriptor(IMG_HORIZONTAL.getImageDescriptor());
		vaction = new Action("ver", Action.AS_RADIO_BUTTON) {
			@Override
			public void run() {
				sashForm.setOrientation(SWT.VERTICAL);
				form.reflow(true);
			}
		};
		vaction.setChecked(false);
		vaction.setToolTipText("Vertical orientation");
		vaction.setImageDescriptor(IMG_VERTICAL.getImageDescriptor());

    }

    private void contributeToActionBars() {
    	fillLocalToolBar(getManagedForm().getForm().getToolBarManager());
    	getManagedForm().getForm().updateToolBar();
    }

    private void fillLocalToolBar(IToolBarManager manager) {
        manager.add(createAction);
		manager.add(haction);
		manager.add(vaction);
    }
    
    private void hookContextMenu() {
        MenuManager menuMgr = new MenuManager("#PopupMenu");
        menuMgr.setRemoveAllWhenShown(true);
        menuMgr.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager manager) {
                fillContextMenu(manager);
            }
        });
        Menu menu = menuMgr.createContextMenu(viewer.getControl());
        viewer.getControl().setMenu(menu);
    }

    private void fillContextMenu(IMenuManager manager) {
        manager.add(createAction);
        manager.add(deleteAction);
        manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
    }

	/**
	 * @see org.eclipse.ui.forms.AbstractFormPart#refresh()
	 */
	@Override
	public void refresh() {
		super.refresh();
		viewer.refresh(true);
	}

	/**
	 * @see com.wgo.precise.client.ui.view.facade.IModelUpdateListener#onModelUpdate(IModelPersistable)
	 */
	public void onModelUpdate(IModelPersistable item) {
		refresh();
	}

	public void onModelItemDeleted(IModelPersistable item, INodeParent parent) {
		if (item instanceof PropertySetWrapper) {
			refresh();
		}
	}

	public void onNewModelItemCreated(IModelPersistable item) {
		if (item instanceof PropertySetWrapper) {
			refresh();
		}
	}

	public void onModelChange(IModelPersistable item) {}
	
}

